from asyncore import dispatcher
from asynchat import async_chat
import socket, asyncore
PORT = 5005
NAME = 'TestChat'

class ChatSession(async_chat):
    def __init__(self, server, sock, uname):
        # Standard setup tasks:
        async_chat.__init__(self, sock)
        self.server = server
        self.uname = uname
        self.set_terminator("\r\n")
        self.data = []
        # Greet the user:
        self.push('Welcome to %s\r\n' % self.server.name)
    def collect_incoming_data(self, data):
        self.data.append(data)
    def found_terminator(self):
        line = ''.join(self.data)
        line = self.uname + ": " + line
        print line
        self.data = []
        self.server.broadcast(line, self.uname)
    def handle_close(self):
        async_chat.handle_close(self)
        self.server.disconnect(self, self.uname)

class ChatServer(dispatcher):
    def __init__(self, port, name):
        # Standard setup tasks
        dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(('', port))
        self.listen(5)
        self.name = name
        self.sessions = []
    def disconnect(self, session, uname):
        self.sessions.remove((uname, session))
        print(uname + " disconnected")
    def broadcast(self, line, uname):
        print line
        for name, session in self.sessions:
            session.push(line + '\r\n')
    def handle_accept(self):
        conn, addr = self.accept()
        uname = conn.recv(32)       
        uname = uname.rstrip("\n\r") 
        print(uname + "connected")
        self.sessions.append((uname, ChatSession(self, conn, uname)))

if __name__ == '__main__':
    s = ChatServer(PORT, NAME)
    asyncore.loop()
